package cn;

import org.jetbrains.annotations.NotNull;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileReader;
import java.util.Properties;

import cn.util.ScanLoaderUtil;

public class AndroidScanner {

    public static void main(String[] args) {

        int len = args.length;
        if(len ==0 ){
            throw new IllegalArgumentException("Please Input Scanner Type");
        }
        String dirName = getWorkDirName(args[0]);
        if(dirName==null){
            throw new IllegalArgumentException("Please Input Work Director");
        }
        Properties properties = readProperties(dirName);

        String androidSDK = properties.getProperty("sdk.dir");
        File platforms = new File(androidSDK,"platforms");
        File sdkFile = findBestSdk(platforms);

        if(sdkFile==null){
            throw new IllegalArgumentException("Android Sdk Not found,Please config sdk.dir in local.properties");
        }

        System.out.println("WorkDir: "+dirName);

        String buildDir = properties.getProperty("app.build.dir");
        String jarlibs = properties.getProperty("app.jar.dir.rules");

        if(jarlibs==null || jarlibs.length()==0){
            throw new IllegalArgumentException("Please config app.jar.dir.rules in local.properties");
        }

        startScanTask(dirName,buildDir,jarlibs,sdkFile);
    }

    private static void startScanTask(String workDir,String buildDir,String jarlibRules,File sdkDir) {
        File file = null;
        if(buildDir==null || buildDir.length()==0){
             file = readRootProjectPath(workDir);
        }else{
             file = new File(workDir,buildDir);
            if(!file.exists()){
                file = new File(buildDir);
            }
        }

        if(file==null || !file.exists()){
            throw new IllegalArgumentException("FileNotFound,app.build value is invalid");
        }

        ScanLoaderTask classLoaderFindTask = new ScanLoaderTask(workDir,file.getAbsolutePath(),jarlibRules,sdkDir);
        ScanLoaderUtil.initClassPath(classLoaderFindTask);

    }

    private static File readRootProjectPath(String workDir) {
        File file = new File(workDir,"settings.gradle");
        BufferedReader bufferedReader = null;
        try {
             bufferedReader = new BufferedReader(new FileReader(file));
             String str = null;
             String projectKey = "rootProject.name";
             String prev = projectKey+"=";
             String projectName = null;
             while ((str=bufferedReader.readLine())!=null){
                 if(str.length()==0) continue;

                 int index = str.trim().indexOf(prev);
                 if(index<0) continue;
                 String projectBlockStr = str.substring(index+prev.length());
                 if(projectBlockStr.startsWith("'") || projectBlockStr.startsWith("\"")){
                     projectName = projectBlockStr.substring(1,projectBlockStr.length()-1);
                 }else{
                     projectName = projectBlockStr;
                 }
                 break;
             }

             if(projectName==null || projectName.length()==0) {
                 return null;
             }
             return new File(workDir,projectName+File.separator+"build");

        } catch (Exception e) {
           e.printStackTrace();
        }
        return null;
    }

    private static File findBestSdk(File platforms) {
        if(!platforms.exists()) return null;
        File[] files = platforms.listFiles();
        if(files==null) return null;
        String  bestNum = null;
        for (File f : files ) {
            String name = f.getName();
            String num = readNumberAtNext(name,"-");
            if(num.length()==0) continue;
            if(bestNum==null){
                bestNum = num;
                continue;
            }
            int dx = bestNum.compareTo(num);
            if(dx<0){
                bestNum = num;
            }
        }
        if(bestNum==null || bestNum.length()==0) return null;
        return new File(platforms,"android-"+bestNum+File.separator+"android.jar");
    }

    private static String readNumberAtNext(String text, String symbol) {
        int lastIndex  = text.lastIndexOf(symbol);
        StringBuilder sb = new StringBuilder();
        if(lastIndex==-1) return sb.toString();


        for (int i=lastIndex+1;i<text.length();i++){
            char ch = text.charAt(i);
            if(ch>='0' && ch<='9'){
                sb.append(ch);
            }else if(sb.length()>0){
                break;
            }

        }

        return sb.toString();
    }

    @NotNull
    private static String getWorkDirName(String arg) {
        String rootPath = arg;

        File f = new File(rootPath);
        rootPath = f.getAbsolutePath();

        if(rootPath.endsWith(File.separator+".")){
            rootPath = rootPath.substring(0,rootPath.length()-2);
        }else if(rootPath.endsWith(File.separator+"..")){
            rootPath = rootPath.substring(0,rootPath.length()-3);
            int lastIndex = rootPath.lastIndexOf(File.separator);
            if(lastIndex>=0){
                rootPath = rootPath.substring(0,lastIndex);
            }
        }

        File file = new File(rootPath,"settings.gradle");
        File absFile    = file.getAbsoluteFile();
        File parentFile = absFile.getParentFile();

        while(file!=null &&(!file.exists() || !file.isFile())){
            parentFile = parentFile.getParentFile();
            if(parentFile==null) break;
            file = new File(parentFile,"settings.gradle");
        }
        if(parentFile==null) return null;
        return parentFile.getAbsolutePath();
    }

    public static Properties readProperties(String workDir){
        Properties properties = new Properties();
        File file = null;
        try {
            file = new File(workDir,"local.properties");
            if(file==null || !file.exists() || !file.isFile()) {
                return properties;
            }
            FileInputStream fis = new FileInputStream(file);
            properties.load(fis);
        } catch (Exception e) {
            e.printStackTrace();
        }

        return properties;
    }



}
